#region Copyright (c) 2006-2009 Widgetsphere LLC, All Rights Reserved
//--------------------------------------------------------------------- *
//                          Widgetsphere  LLC                           *
//             Copyright (c) 2006-2009 All Rights reserved              *
//                                                                      *
//                                                                      *
//This file and its contents are protected by United States and         *
//International copyright laws.  Unauthorized reproduction and/or       *
//distribution of all or any portion of the code contained herein       *
//is strictly prohibited and will result in severe civil and criminal   *
//penalties.  Any violations of this copyright will be prosecuted       *
//to the fullest extent possible under law.                             *
//                                                                      *
//THE SOURCE CODE CONTAINED HEREIN AND IN RELATED FILES IS PROVIDED     *
//TO THE REGISTERED DEVELOPER FOR THE PURPOSES OF EDUCATION AND         *
//TROUBLESHOOTING. UNDER NO CIRCUMSTANCES MAY ANY PORTION OF THE SOURCE *
//CODE BE DISTRIBUTED, DISCLOSED OR OTHERWISE MADE AVAILABLE TO ANY     *
//THIRD PARTY WITHOUT THE EXPRESS WRITTEN CONSENT OF WIDGETSPHERE LLC   *
//                                                                      *
//UNDER NO CIRCUMSTANCES MAY THE SOURCE CODE BE USED IN WHOLE OR IN     *
//PART, AS THE BASIS FOR CREATING A PRODUCT THAT PROVIDES THE SAME, OR  *
//SUBSTANTIALLY THE SAME, FUNCTIONALITY AS ANY WIDGETSPHERE PRODUCT.    *
//                                                                      *
//THE REGISTERED DEVELOPER ACKNOWLEDGES THAT THIS SOURCE CODE           *
//CONTAINS VALUABLE AND PROPRIETARY TRADE SECRETS OF WIDGETSPHERE,      *
//INC.  THE REGISTERED DEVELOPER AGREES TO EXPEND EVERY EFFORT TO       *
//INSURE ITS CONFIDENTIALITY.                                           *
//                                                                      *
//THE END USER LICENSE AGREEMENT (EULA) ACCOMPANYING THE PRODUCT        *
//PERMITS THE REGISTERED DEVELOPER TO REDISTRIBUTE THE PRODUCT IN       *
//EXECUTABLE FORM ONLY IN SUPPORT OF APPLICATIONS WRITTEN USING         *
//THE PRODUCT.  IT DOES NOT PROVIDE ANY RIGHTS REGARDING THE            *
//SOURCE CODE CONTAINED HEREIN.                                         *
//                                                                      *
//THIS COPYRIGHT NOTICE MAY NOT BE REMOVED FROM THIS FILE.              *
//--------------------------------------------------------------------- *
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using Widgetsphere.Generator.Models;
using System.Linq;

namespace Widgetsphere.Generator
{
  internal class ValidationHelper
  {
    private ValidationHelper() { }

    public static readonly string ErrorTextInvalidIdentifier = "This identifier '{0}' is the wrong format or contains invalid characters.";
    public static readonly string ErrorTextInvalidCompany = "This company name is the wrong format or contains invalid characters.";
    public static readonly string ErrorTextInvalidCompanyAbbreviation = "This company abbreviation is the wrong format or contains invalid characters.";
    public static readonly string ErrorTextInvalidProject = "This project name is the wrong format or contains invalid characters.";
    public static readonly string ErrorTextInvalidDatabase = "This database name is the wrong format or contains invalid characters.";
    public static readonly string ErrorTextInvalidCodeFacade = "The code facade is the wrong format or contains invalid characters.";
    public static readonly string ErrorTextSQLRequired = "The SQL text is required.";
    public static readonly string ErrorTextPackageRequiresDisplayName = "Package objects must have a display name!";
    public static readonly string ErrorTextDuplicateName = "An object named '{0}' is already defined in this scope.";
		public static readonly string ErrorTextComponentTableDuplicateName = "The component named '{0}' has a duplicate name with a table.";
		public static readonly string ErrorTextDuplicateCodeFacade = "The object named '{0}' has a conflicting name or codefacade in this scope.";
    public static readonly string ErrorTextColumnsRequired = "The object must have at least one generated column.";
    public static readonly string ErrorTextNoPrimaryKey = "One or more columns must be marked as a primary key.";
    public static readonly string ErrorTextPrimaryKeyNull = "A primary key cannot allow null values. AllowNull must be false.";
		public static readonly string ErrorTextInvalidIdentityColumn = "Columns marked as identity must be of type Int, BigInt, TinyInt, SmallInt, or UniqueIdentifier";
    public static readonly string ErrorTextTypeTableNoData = "Type tables must have static data defined.";
    public static readonly string ErrorTextRelationshipTypeMismatch = "Columns that make-up relationships must be of the same type.";
    public static readonly string ErrorTextDuplicateRoleName = "All relations must have a unique role name for table {0}.";
    public static readonly string ErrorTextRelationMustHaveParentChild = "All relations must have a parent and child table defined.";
		public static readonly string ErrorTextTableColumnNameMatch = "A column cannot have the same name as its parent table.";
		public static readonly string ErrorTextColumnDuplicateNameMatch = "Duplicate column name.";
		public static readonly string ErrorTextPreDefinedNameField = "The column '{0}' cannot use the predefined name.";
		public static readonly string ErrorTextInvalidInheritance = "The inheritance chain is not valid. All tables must have the same primary keys in type and name and other fields must have unique names across the inheritance chain.";
		public static readonly string ErrorTextNoTables = "There must be one or more tables defined.";
		public static readonly string ErrorTextNoColumns = "All tables must one or more columns defined.";
		public static readonly string ErrorTextMinMaxValueMismatch = "The minimum value cannot be greater than the maximum value.";
		public static readonly string ErrorTextMinMaxValueInvalidType = "The minimum and maximum values can only be set for numeric fields.";
		public static readonly string ErrorTextTableDoesNotAllowModification = "The table '{0}' does not allow modification so cannot be unit tested.";
		public static readonly string ErrorTextTableColumnNonPrimaryRelationNotUnique = "The column {0} in table '{1}' must be marked unique because there is a non-primary key relationship that depends on it.";
		public static readonly string ErrorTextTableProjectSameName = "The table '{0}' cannot have the same name as the project.";
		public static readonly string ErrorTextTableCompositeNoColumns = "The table composite '{0}' must have at least one column.";
		public static readonly string ErrorTextTableComponentNoColumns = "The table component '{0}' must have at least one column.";
		public static readonly string ErrorTextTypeTableIsWritable = "The type table '{0}' is writable. It is recommended that this table have its AllowModification property set to false.";
		public static readonly string ErrorTextMutableInherit = "The table '{0}' is mutable and it inherited from the immutable table '{1}'. This must be changed.";
		public static readonly string ErrorTextTypeTableIsMutable = "The type table '{0}' must be marked as immutable.";
		public static readonly string ErrorTextBaseTableNonGenerated = "The base table '{0}' of table '{1}' is not marked for generation.";
		public static readonly string ErrorTextConflictingRelationships = "The following tables have conflicting relationships: {0}. Delete one or more rleationships or assign role names to them.";
		public static readonly string ErrorTextComponentMustHaveTablePK = "The table component {0} must include the primary keys for from the parent table.";
		public static readonly string ErrorTextChildTableRelationIdentity = "The relationship is based on an identity column in the table '{0}' mapping to another identity column in table '{1}'. This is not valid.";
		public static readonly string ErrorTextNameConfictsWithGeneratedCode = "The table '{0}' will conflict with generated code. Please change the name.";
		
    public const string ValidCodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
		//private const string reservedSQLWords = "ENCRYPTION,ORDER,ADD,END,OUTER,ALL,ERRLVL,OVER,ALTER,ESCAPE,PERCENT,AND,EXCEPT,PLAN,ANY,EXEC,PRECISION,AS,EXECUTE,PRIMARY,ASC,EXISTS,PRINT,AUTHORIZATION,EXIT,PROC,AVG,EXPRESSION,PROCEDURE,BACKUP,FETCH,PUBLIC,BEGIN,FILE,RAISERROR,BETWEEN,FILLFACTOR,READ,BREAK,FOR,READTEXT,BROWSE,FOREIGN,RECONFIGURE,BULK,FREETEXT,REFERENCES,BY,FREETEXTTABLE,REPLICATION,CASCADE,FROM,RESTORE,CASE,FULL,RESTRICT,CHECK,FUNCTION,RETURN,CHECKPOINT,GOTO,REVOKE,CLOSE,GRANT,RIGHT,CLUSTERED,GROUP,ROLLBACK,COALESCE,HAVING,ROWCOUNT,COLLATE,HOLDLOCK,ROWGUIDCOL,COLUMN,IDENTITY,RULE,COMMIT,IDENTITY_INSERT,SAVE,COMPUTE,IDENTITYCOL,SCHEMA,CONSTRAINT,IF,SELECT,CONTAINS,IN,SESSION_USER,CONTAINSTABLE,INDEX,SET,CONTINUE,INNER,SETUSER,CONVERT,INSERT,SHUTDOWN,COUNT,INTERSECT,SOME,CREATE,INTO,STATISTICS,CROSS,IS,SUM,CURRENT,JOIN,SYSTEM_USER,CURRENT_DATE,KEY,TABLE,CURRENT_TIME,KILL,TEXTSIZE,CURRENT_TIMESTAMP,LEFT,THEN,CURRENT_USER,LIKE,TO,CURSOR,LINENO,TOP,DATABASE,LOAD,TRAN,DATABASEPASSWORD,MAX,TRANSACTION,DATEADD,MIN,TRIGGER,DATEDIFF,NATIONAL,TRUNCATE,DATENAME,NOCHECK,TSEQUAL,DATEPART,NONCLUSTERED,UNION,DBCC,NOT,UNIQUE,DEALLOCATE,NULL,UPDATE,DECLARE,NULLIF,UPDATETEXT,DEFAULT,OF,USE,DELETE,OFF,USER,DENY,OFFSETS,VALUES,DESC,ON,VARYING,DISK,OPEN,VIEW,DISTINCT,OPENDATASOURCE,WAITFOR,DISTRIBUTED,OPENQUERY,WHEN,DOUBLE,OPENROWSET,WHERE,DROP,OPENXML,WHILE,DUMP,OPTION,WITH,ELSE,OR,WRITETEXT";
		//private const string reservedCSharpWords = "_Bool,_Complex,_Imaginary,_Packed,abstract,as,auto,base,bool,break,byte,case,catch,char,checked,class,const,continue,decimal,default,delegate,do,double,else,enum,event,exception,explicit,extern,false,finally,fixed,float,for,foreach,goto,if,implicit,in,inline,int,interface,internal,is,lock,long,namespace,new,null,object,operator,out,override,params,private,protected,public,readonly,ref,register,restrict,return,sbyte,sealed,short,signed,sizeof,stackalloc,static,string,struct,switch,this,throw,true,try,typedef,typeof,uint,ulong,unchecked,union,unsafe,unsigned,ushort,using,virtual,void,volatile,while";
		private const string reservedSQLWords = "";
		private const string reservedCSharpWords = "_Bool,_Complex,_Imaginary,_Packed,abstract,as,auto,base,bool,break,byte,case,catch,char,checked,class,const,continue,decimal,default,delegate,do,double,else,enum,event,exception,explicit,extern,false,finally,fixed,float,for,foreach,goto,if,implicit,in,inline,int,interface,internal,is,lock,long,namespace,new,null,object,operator,out,override,params,private,protected,public,readonly,ref,register,restrict,return,sbyte,sealed,short,signed,sizeof,stackalloc,static,string,struct,switch,this,throw,true,try,typedef,typeof,uint,ulong,unchecked,union,unsafe,unsigned,ushort,using,virtual,void,volatile,while,PrimaryKey,attribute,businessobject,attribute,system,BusinessCollectionBase,BusinessCollectionPersistableBase,BusinessObjectBase,BusinessObjectList,BusinessObjectPersistableBase,IVisitee,IVisitor,IAuditable,IPagingObject,IPagingFieldItem,DomainCollectionBase,Enumerations,IBusinessCollection,IBusinessObject,IBusinessObjectSearch,IDomainCollection,IDomainObject,IErrorRow,IPersistableBusinessCollection,IPersistableBusinessObject,IPersistableDomainObject,IPrimaryKey,IPropertyBag,IPropertyDefine,IReadOnlyBusinessCollection,IReadOnlyBusinessObject,ITyped,IWrappingClass,PersistableDomainCollectionBase,PersistableDomainObjectBase,PrimaryKey,ReadOnlyDomainCollection,ReadOnlyDomainObjectBase,SelectCommand,StoredProcedure,StoredProcedureFactory,SubDomainBase,SubDomainWrapper,BusinessObjectCancelEventArgs,BusinessObjectEventArgs,ConcurrencyException,DefaultLogConfiguration,ILogClass,ILogConfiguration,MultiProcessTraceListener,TraceSwitchAttribute,IXmlable,IBoolFieldDescriptor,IDateFieldDescriptor,IFieldDescriptor,IFloatFieldDescriptor,IIntegerFieldDescriptor,IStringFieldDescriptor";

    public static bool ValidDatabaseIdenitifer(string name)
    {
      if (name.Length == 0)
        return false;

			string[] words = reservedSQLWords.ToLower().Split(',');

			var q = (from x in words
							 where name.ToLower() == x
							 select x).FirstOrDefault();

			if (q != null)
				return false;

			//The database does actualy allow spaces
			string validchars2 = ValidCodeChars + " /#";

      foreach (char c in name)
      {
				if (validchars2.IndexOf(c) == -1)
          return false;
      }
      return true;
    }

		public static bool ValidCodeIdenitifer(string name)
		{
			if (name.Length == 0)
				return false;

			string[] words = reservedCSharpWords.ToLower().Split(',');

			var q = (from x in words
							 where name.ToLower() == x
							 select x).FirstOrDefault();

			if (q != null)
				return false;

			foreach (char c in name)
			{
				if (ValidCodeChars.IndexOf(c) == -1)
					return false;
			}
			return true;
		}

		public static string MakeCodeIdenitifer(string name)
		{
			if (name.Length == 0)
				return "";

			string retval = "";
			string validchars2 = ValidCodeChars;

			foreach (char c in name)
			{
				if (validchars2.IndexOf(c) == -1)
					retval += "_";
				else
					retval += c;
			}
			return retval;
		}

    public static string MakeDatabaseIdenitifer(string name)
    {
      if(name.Length == 0)
        return "";

      string retval = "";
			string validchars2 = ValidCodeChars + " /#";

      foreach(char c in name)
      {
				if (validchars2.IndexOf(c) == -1)
          retval += "_";
        else
          retval += c;
      }
      return retval;
    }

		public static void AppendCopyrightInCode(StringBuilder sb, ModelRoot model)
		{
			if ((model.Copyright != null) && (model.Copyright != ""))
			{
				sb.AppendLine("#region Copyright (c) " + DateTime.Now.Year + " " + model.CompanyName + ", All Rights Reserved");
				  
				string temp = model.Copyright.Replace("\r\n", "\n");
				temp = temp.Replace("\r", "\n");
				temp = temp.Replace("%year%", DateTime.Now.Year.ToString());
				string[] arr = temp.Split('\n');
				foreach (string s in arr)
				{
					sb.AppendLine("//" + s);
				}
				sb.AppendLine("#endregion");
				sb.AppendLine();
			}
		}

		public static void AppendCopyrightInSQL(StringBuilder sb, ModelRoot model)
		{
			if ((model.Copyright != null) && (model.Copyright != ""))
			{
				sb.AppendLine("--Copyright (c) " + DateTime.Now.Year + " " + model.CompanyName + ", All Rights Reserved");

				string temp = model.Copyright.Replace("\r\n", "\n");
				temp = temp.Replace("\r", "\n");
				temp = temp.Replace("%year%", DateTime.Now.Year.ToString());
				string[] arr = temp.Split('\n');
				foreach (string s in arr)
				{
					sb.AppendLine("--" + s);
				}				
				sb.AppendLine();
			}
		}

  }
}
